import processing.bluetooth.*;

final int ACTION_START = 1;
final int ACTION_LIST  = 2;
final int ACTION_CONNECT  = 3;
final int ACTION_PLAY  = 4;

int action;
int command;
String infoText;

Bluetooth bt;
Service[] services;
Device[] devices;
Client c;
PFont defaultFont, commandFont;
PList list;
PScrollBar scroll;
color bg;
PImage logo, title, headChoose, headPlay, colmeiaLogo;
PImageLabel logoLabel, headChooseLabel, headPlayLabel;
int y;
int listLoaded = 0;
String actualKey;

void setup() 
{
  bg = color(253, 184, 19);
  background(bg);
  bt = new Bluetooth(this);
  bt.discover();
  scroll = new PScrollBar();
  list = new PList();  

  commandFont = loadFont("HelveticaRoundedLTStd-Black-127.mvlw"); 
  defaultFont = loadFont("FFFUrban-8.mvlw"); 
  title = loadImage("m2s_logo.png");
  headChoose = loadImage("head_choose_server.png");
  headPlay = loadImage("head_ready_play.png");  
  action = ACTION_START;  
}

void draw()
{ 
  background(bg);
  
  switch (action) {
    case ACTION_START:
      displayInfo("SEARCHING SERVERS");
      break;     
    case ACTION_LIST:
      displayList();
      break;
    case ACTION_CONNECT:
      displayInfo("CONNECTING");
      break;
    case ACTION_PLAY:
      displayKeys(actualKey);
      break;      
    default:
      theBear();
  }   
}

void libraryEvent(Object library, int event, Object data) {
  if (library == list) {
    if (listLoaded == 1) {
      String item = (String) list.get(list.selected);
      for (int i = 0; i < devices.length; i++) {
        if (devices[i].name == item) {
          action = ACTION_CONNECT;
          devices[i].discover();
        }
      }
    }
  }  
  
  if (library == bt) {
    switch (event) {
      case Bluetooth.EVENT_DISCOVER_DEVICE_COMPLETED:
        action = ACTION_LIST;
        devices = (Device[]) data;
        break;

      case Bluetooth.EVENT_DISCOVER_SERVICE:
        services = (Service[]) data;
        break;

      case Bluetooth.EVENT_DISCOVER_SERVICE_COMPLETED:
        c = (Client) services[0].connect();
        if (c != null) {
          action = ACTION_PLAY;
        }
        break;
    }
  }
}

void displayList()
{
  if (length(devices) > 0) {
     image(headChoose, 0, 0);
     y = 40;
     if (listLoaded == 0) {
       scroll.setBounds(width - 4, y, 4, height - y);
       list.scrollbar = scroll;
       list.setBounds(0, y, width - 4, height - y);
       for (int i = 0; i < length(devices); i++) {
         list.add(devices[i].name);
       }
       list.initialize();
       list.acceptFocus();     
     }
     list.draw();
     listLoaded = 1;
   } else {
     displayInfo("NO SERVERS FOUND");
   }    
}

void displayInfo(String message)
{
  image(title, (width - title.width) / 2, 
               (height - title.height) / 2);
  y = 19;
  textFont(defaultFont);
  textAlign(CENTER);
  fill(0);
  text(message, (width / 2), (height / 2) + y);
}

void displayKeys(String theKey) 
{
  image(headPlay, 0, 0);
  if (actualKey != null) {
    textFont(commandFont);
    textAlign(RIGHT);
    text(theKey, (width - 4), (height - 4));
  }
}

void keyPressed() 
{
  list.keyPressed();
  if (action == ACTION_PLAY) {
    actualKey = getKey(rawKeyCode);
    c.writeUTF(actualKey + ",down");
    c.flush();    
  }
}

void keyReleased()
{
  list.keyReleased();
  if (action == ACTION_PLAY) {
    actualKey = getKey(rawKeyCode);
    c.writeUTF(actualKey + ",up");
    c.flush();    
  }  
}

void theBear()
{
  image(colmeiaLogo, (width / 2), (width / 2));
}

String getKey(int code)
{
  String thekey = "";
  switch (code) {
    case 49:
      thekey = "1";
    break;
    case 50:
      thekey = "2";
    break;
    case 51:
      thekey = "3";
    break;
    case 52:
      thekey = "4";
    break;
    case 53:
      thekey = "5";
    break;
    case 54:
      thekey = "6";
    break;
    case 55:
      thekey = "7";
    break;
    case 56:
      thekey = "8";
    break;
    case 57:
      thekey = "9";
    break;
    case 42:
      thekey = "*";
    break;
    case 48:
      thekey = "0";
    break;
    case 35:
      thekey = "#";
    break;
    case -5:
      thekey = "E";
    break;
    case -3:
      thekey = "L";
    break;
    case -4:
      thekey = "R";
    break;
    case -2:
      thekey = "D";
    break;
    case -1:
      thekey = "U";
    break;    
  }
  return thekey;
}
